import { PromptVariable, VariableReplacement } from '@/types/prompt';

/**
 * 从提示词模板中提取变量
 * @param template 提示词模板字符串
 * @returns 变量名数组
 */
export function extractVariables(template: string): string[] {
  const regex = /\{([^}]+)\}/g;
  const variables = new Set<string>();
  let match;
  
  while ((match = regex.exec(template)) !== null) {
    variables.add(match[1]);
  }
  
  return Array.from(variables);
}

/**
 * 验证变量值
 * @param variable 变量定义
 * @param value 变量值
 * @returns 验证结果
 */
export function validateVariable(variable: PromptVariable, value: any): {
  valid: boolean;
  error?: string;
} {
  // 检查必需变量
  if (variable.required && (value === undefined || value === null || value === '')) {
    return {
      valid: false,
      error: `变量 ${variable.name} 是必需的`
    };
  }

  // 如果不是必需且没有值，直接返回有效
  if (!variable.required && (value === undefined || value === null || value === '')) {
    return { valid: true };
  }

  // 类型验证
  switch (variable.type) {
    case 'string':
      if (typeof value !== 'string') {
        return {
          valid: false,
          error: `变量 ${variable.name} 必须是字符串类型`
        };
      }
      // 正则验证
      if (variable.validation) {
        const regex = new RegExp(variable.validation);
        if (!regex.test(value)) {
          return {
            valid: false,
            error: `变量 ${variable.name} 格式不正确`
          };
        }
      }
      break;

    case 'number':
      const num = typeof value === 'number' ? value : Number(value);
      if (isNaN(num)) {
        return {
          valid: false,
          error: `变量 ${variable.name} 必须是数字类型`
        };
      }
      // 范围验证
      if (variable.min !== undefined && num < variable.min) {
        return {
          valid: false,
          error: `变量 ${variable.name} 不能小于 ${variable.min}`
        };
      }
      if (variable.max !== undefined && num > variable.max) {
        return {
          valid: false,
          error: `变量 ${variable.name} 不能大于 ${variable.max}`
        };
      }
      break;

    case 'select':
      if (!variable.options?.includes(value)) {
        return {
          valid: false,
          error: `变量 ${variable.name} 必须是以下选项之一: ${variable.options?.join(', ')}`
        };
      }
      break;

    case 'boolean':
      if (typeof value !== 'boolean') {
        return {
          valid: false,
          error: `变量 ${variable.name} 必须是布尔值`
        };
      }
      break;
  }

  return { valid: true };
}

/**
 * 验证所有变量
 * @param variables 变量定义列表
 * @param values 变量值映射
 * @returns 验证结果
 */
export function validateAllVariables(
  variables: PromptVariable[],
  values: Record<string, any>
): {
  valid: boolean;
  errors: string[];
} {
  const errors: string[] = [];

  for (const variable of variables) {
    const value = values[variable.name];
    const result = validateVariable(variable, value);
    
    if (!result.valid && result.error) {
      errors.push(result.error);
    }
  }

  return {
    valid: errors.length === 0,
    errors
  };
}

/**
 * 替换模板中的变量
 * @param template 模板字符串
 * @param variables 变量定义列表
 * @param values 变量值映射
 * @returns 替换结果
 */
export function replaceVariables(
  template: string,
  variables: PromptVariable[],
  values: Record<string, any>
): VariableReplacement {
  // 验证变量
  const validation = validateAllVariables(variables, values);
  if (!validation.valid) {
    return {
      original: template,
      replaced: template,
      variables: values,
      errors: validation.errors
    };
  }

  // 处理变量值，应用默认值
  const processedValues: Record<string, any> = {};
  for (const variable of variables) {
    const value = values[variable.name];
    if (value === undefined || value === null || value === '') {
      processedValues[variable.name] = variable.defaultValue ?? '';
    } else {
      processedValues[variable.name] = value;
    }
  }

  // 替换变量
  let replaced = template;
  for (const [name, value] of Object.entries(processedValues)) {
    const regex = new RegExp(`\\{${name}\\}`, 'g');
    replaced = replaced.replace(regex, String(value));
  }

  return {
    original: template,
    replaced,
    variables: processedValues
  };
}

/**
 * 预处理变量值
 * @param value 原始值
 * @param preprocessor 预处理函数名
 * @returns 处理后的值
 */
export function preprocessVariableValue(
  value: string,
  preprocessor?: 'uppercase' | 'lowercase' | 'capitalize' | 'trim'
): string {
  if (!preprocessor) return value;

  switch (preprocessor) {
    case 'uppercase':
      return value.toUpperCase();
    case 'lowercase':
      return value.toLowerCase();
    case 'capitalize':
      return value.charAt(0).toUpperCase() + value.slice(1).toLowerCase();
    case 'trim':
      return value.trim();
    default:
      return value;
  }
}

/**
 * 获取变量的显示名称
 * @param variable 变量定义
 * @returns 显示名称
 */
export function getVariableDisplayName(variable: PromptVariable): string {
  return variable.description || variable.name;
}

/**
 * 获取变量的输入组件类型
 * @param variable 变量定义
 * @returns 输入组件类型
 */
export function getVariableInputType(variable: PromptVariable): string {
  switch (variable.type) {
    case 'string':
      return 'text';
    case 'number':
      return 'number';
    case 'select':
      return 'select';
    case 'boolean':
      return 'checkbox';
    default:
      return 'text';
  }
}

/**
 * 检查模板中是否有未定义的变量
 * @param template 模板字符串
 * @param variables 已定义的变量列表
 * @returns 未定义的变量名列表
 */
export function findUndefinedVariables(
  template: string,
  variables: PromptVariable[]
): string[] {
  const extractedVars = extractVariables(template);
  const definedVars = new Set(variables.map(v => v.name));
  
  return extractedVars.filter(v => !definedVars.has(v));
}

/**
 * 检查是否有未使用的变量定义
 * @param template 模板字符串
 * @param variables 变量定义列表
 * @returns 未使用的变量列表
 */
export function findUnusedVariables(
  template: string,
  variables: PromptVariable[]
): PromptVariable[] {
  const extractedVars = new Set(extractVariables(template));
  
  return variables.filter(v => !extractedVars.has(v.name));
}

/**
 * 生成变量输入表单的初始值
 * @param variables 变量定义列表
 * @returns 初始值映射
 */
export function generateInitialValues(variables: PromptVariable[]): Record<string, any> {
  const values: Record<string, any> = {};
  
  for (const variable of variables) {
    if (variable.defaultValue !== undefined) {
      values[variable.name] = variable.defaultValue;
    } else {
      switch (variable.type) {
        case 'string':
          values[variable.name] = '';
          break;
        case 'number':
          values[variable.name] = variable.min ?? 0;
          break;
        case 'select':
          values[variable.name] = variable.options?.[0] ?? '';
          break;
        case 'boolean':
          values[variable.name] = false;
          break;
      }
    }
  }
  
  return values;
}